#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200010;

int n, m; // n 个点 m 条边
int p[N];

struct Edge // 存储每条边的信息
{
    int a, b, w;
    bool operator<(const Edge &W) const
    {
        return w < W.w;
    }
} edges[N];

int find(int x) // 寻找并查集
{
    if (p[x] != x)
        p[x] = find(p[x]);
    return p[x];
}

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) // 输入所有边
    {
        int a, b, w;
        scanf("%d%d%d", &a, &b, &w);
        edges[i] = {a, b, w};
    }

    sort(edges, edges + m); // 将所有边按从大到小排序

    for (int i = 0; i <= n; i++) // 生成每个点所在集合
        p[i] = i;

    int res = 0, cnt = 0;
    for (int i = 0; i < m; i++) // 枚举每条边
    {
        int a = edges[i].a, b = edges[i].b, w = edges[i].w;
        a = find(a), b = find(b); // 找到ab所在的并查集
        if (a != b)               // 如果ab不连通
        {
            p[a] = b; // 将b加入到集合中
            res += w; // 累加权重之和
            cnt++;    // 最小生成树的点+1
        }
        if (cnt < n - 1)
            puts("impossible");
        else
            printf("%d\n", res);
    }
}